﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;
using System.IO;
using System.Xml.Serialization;

namespace FortDoneQuicker
{
    public partial class Form1 : Form
    {
        private Color cellBgColor = Color.Empty;
        private Color cellDigColor = Color.FromArgb(255, 156, 119, 57);

        public Form1()
        {
            InitializeComponent();

            createDataGridViewCells(15, 20);
            resizeDataGridViewCells(16);
            setStartingPosition(0, 0);
        }

        //grid functionality
        private void createDataGridViewCells(int nbRows, int nbColumns)
        {
            for (int i = 0; i < nbColumns; i++)
            {
                dataGridView1.Columns.Add("", "");
            }
            for (int i = 0; i < nbRows; i++)
            {
                dataGridView1.Rows.Add();
            }
        }
        private void clearDataGridViewCells()
        {
            for (int i = 0; i < dataGridView1.Rows.Count; i++)
            {
                for (int j = 0; j < dataGridView1.Columns.Count; j++)
                {
                    if (dataGridView1.Rows[i].Cells[j].Style.BackColor == cellDigColor)
                    {
                        dataGridView1.Rows[i].Cells[j].Style.BackColor = cellBgColor;
                    }
                }
            }
        }
        private void buttonClearCells_Click(object sender, EventArgs e)
        {
            clearDataGridViewCells();
        }

        //change cell size
        private void resizeDataGridViewCells(int cellSize)
        {
            for (int i = 0; i < dataGridView1.Rows.Count; i++)
            {
                dataGridView1.Rows[i].Height = cellSize;
            }
            for (int i = 0; i < dataGridView1.Columns.Count; i++)
            {
                dataGridView1.Columns[i].Width = cellSize;
            }
        }
        private void numericUpDownCellSize_ValueChanged(object sender, EventArgs e)
        {
            int cellSize = (int)numericUpDownCellSize.Value;
            resizeDataGridViewCells(cellSize);
        }

        //add rows and columns
        private void addLeftColumns(int nb)
        {
            for (int i = 0; i < nb; i++)
            {
                DataGridViewColumn c = new DataGridViewColumn();
                c.CellTemplate = new DataGridViewTextBoxCell();
                dataGridView1.Columns.Insert(0, c);
            }
        }
        private void addRightColumns(int nb)
        {
            for (int i = 0; i < nb; i++)
            {
                dataGridView1.Columns.Add("", "");
            }
        }
        private void addTopRows(int nb)
        {
            dataGridView1.Rows.Insert(0, nb);
        }
        private void addBottomRows(int nb)
        {
            //the AllowUserToAddRows property of the DataGridView needs to be set to false
            //in order for this to add rows at the bottom. Otherwise it inserts rows right
            //above the last row, pushing the previously last row to the bottom.
            for (int i = 0; i < nb; i++)
            {
                dataGridView1.Rows.Add();
            }
        }

        private void buttonAddLeftColumn_Click(object sender, EventArgs e)
        {
            int cellSize = dataGridView1.Rows[0].Cells[0].Size.Width;
            addLeftColumns(1);
            resizeDataGridViewCells(cellSize);
        }
        private void buttonAddRightColumn_Click(object sender, EventArgs e)
        {
            int cellSize = dataGridView1.Rows[0].Cells[0].Size.Width;
            addRightColumns(1);
            resizeDataGridViewCells(cellSize);
        }
        private void buttonAddTopRow_Click(object sender, EventArgs e)
        {
            int cellSize = dataGridView1.Rows[0].Cells[0].Size.Width;
            addTopRows(1);
            resizeDataGridViewCells(cellSize);
        }
        private void buttonAddBottomRow_Click(object sender, EventArgs e)
        {
            int cellSize = dataGridView1.Rows[0].Cells[0].Size.Width;
            addBottomRows(1);
            resizeDataGridViewCells(cellSize);
        }

        //remove rows and columns
        private void removeLeftColumns(int nb)
        {
            for (int i = 0; i < nb && dataGridView1.Columns.Count > 1; i++)
            {
                dataGridView1.Columns.RemoveAt(0);
            }
        }
        private void removeRightColumns(int nb)
        {
            for (int i = 0; i < nb && dataGridView1.Columns.Count > 1; i++)
            {
                dataGridView1.Columns.RemoveAt(dataGridView1.Columns.Count - 1);
            }
        }
        private void removeTopRows(int nb)
        {
            for (int i = 0; i < nb && dataGridView1.Rows.Count > 1; i++)
            {
                dataGridView1.Rows.RemoveAt(0);
            }
        }
        private void removeBottomRows(int nb)
        {
            for (int i = 0; i < nb && dataGridView1.Rows.Count > 1; i++)
            {
                dataGridView1.Rows.RemoveAt(dataGridView1.Rows.Count - 2);
            }
        }

        private void buttonRemoveLeftColumn_Click(object sender, EventArgs e)
        {
            int cellSize = dataGridView1.Rows[0].Cells[0].Size.Width;
            removeLeftColumns(1);
            resizeDataGridViewCells(cellSize);
        }
        private void buttonRemoveRightColumn_Click(object sender, EventArgs e)
        {
            int cellSize = dataGridView1.Rows[0].Cells[0].Size.Width;
            removeRightColumns(1);
            resizeDataGridViewCells(cellSize);
        }
        private void buttonRemoveTopRow_Click(object sender, EventArgs e)
        {
            int cellSize = dataGridView1.Rows[0].Cells[0].Size.Width;
            removeTopRows(1);
            resizeDataGridViewCells(cellSize);
        }
        private void buttonRemoveBottomRow_Click(object sender, EventArgs e)
        {
            int cellSize = dataGridView1.Rows[0].Cells[0].Size.Width;
            removeBottomRows(1);
            resizeDataGridViewCells(cellSize);
        }

        //saving and loading
        private void save()
        {
            Grid grid = createGridFromDGV();
            grid.saveXML();
        }
        private void load()
        {
            Grid grid = new Grid();
            grid.loadXML();
            updateDGVFromGrid(grid);
        }
        private Grid createGridFromDGV()
        {
            Grid grid = new Grid();
            grid.nbRows = dataGridView1.Rows.Count;
            grid.nbColumns = dataGridView1.Rows[0].Cells.Count;
            grid.actions = new List<List<Action>>();

            for (int i = 0; i < grid.nbRows; i++)
            {
                for (int j = 0; j < grid.nbColumns; j++)
                {
                    grid.actions.Add(new List<Action>());

                    if (dataGridView1.Rows[i].Cells[j].Style.BackColor == cellDigColor) { grid[i, j].Add(Action.Dig); }
                    else { grid[i, j].Add(Action.None); }
                }
            }
            return grid;
        }
        private void updateDGVFromGrid(Grid grid)
        {
            //change amount of rows
            int currentNbRows = dataGridView1.Rows.Count;
            int deltaRows = grid.nbRows - currentNbRows;
            if (deltaRows > 0) { addBottomRows(deltaRows); }
            else if (deltaRows < 0) { removeBottomRows(-deltaRows); }

            //change amount of columns
            int currentNbColumns = dataGridView1.Rows[0].Cells.Count;
            int deltaColumns = grid.nbColumns - currentNbColumns;
            if (deltaColumns > 0) { addRightColumns(deltaColumns); }
            else if (deltaColumns < 0) { removeRightColumns(-deltaColumns); }

            //change dataGridView
            for (int i = 0; i < grid.nbRows; i++)
            {
                for (int j = 0; j < grid.nbColumns; j++)
                {
                    List<Action> actions = grid[i, j];
                    for (int k = 0; k < actions.Count; k++)
                    {
                        if (actions[k] == Action.Dig) { dataGridView1.Rows[i].Cells[j].Style.BackColor = cellDigColor; }
                        else { dataGridView1.Rows[i].Cells[j].Style.BackColor = cellBgColor; }
                    }
                }
            }
        }

        //starting position
        private void setStartingPosition(int rowIndex, int columnIndex)
        {
            dataGridView1.Rows[rowIndex].Cells[columnIndex].Style.Alignment = DataGridViewContentAlignment.MiddleCenter;
            dataGridView1.Rows[rowIndex].Cells[columnIndex].Value = "S";
        }
        private void findStartingPosition(out int rowIndex, out int columnIndex)
        {
            rowIndex = -1;
            columnIndex = -1;

            for (int i = 0; i < dataGridView1.Rows.Count; i++)
            {
                for (int j = 0; j < dataGridView1.Columns.Count; j++)
                {
                    if (((string)dataGridView1.Rows[i].Cells[j].Value) == "S")
                    {
                        rowIndex = i;
                        columnIndex = j;
                    }
                }
            }
        }
        private void removeStartingPosition()
        {
            int rowIndex, columnIndex;
            findStartingPosition(out rowIndex, out columnIndex);

            if (rowIndex != -1 && columnIndex != -1)
            {
                dataGridView1.Rows[rowIndex].Cells[columnIndex].Value = "";
            }
        }
        private void buttonSetAsStart_Click(object sender, EventArgs e)
        {
            removeStartingPosition();
            setStartingPosition(dataGridView1.CurrentCell.RowIndex, dataGridView1.CurrentCell.ColumnIndex);
        }

        //digging
        private void toggleDiggingForCell(int rowIndex, int columnIndex)
        {
            if (dataGridView1.Rows[rowIndex].Cells[columnIndex].Style.BackColor == cellBgColor)
            {
                dataGridView1.Rows[rowIndex].Cells[columnIndex].Style.BackColor = cellDigColor;
            }
            else
            {
                dataGridView1.Rows[rowIndex].Cells[columnIndex].Style.BackColor = cellBgColor;
            }
        }
        private void dataGridView1_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                if (dataGridView1.GetCellCount(DataGridViewElementStates.Selected) > 0)
                {
                    //toggle selected cells
                    for (int i = 0; i < dataGridView1.GetCellCount(DataGridViewElementStates.Selected); i++)
                    {
                        int rowIndex = dataGridView1.SelectedCells[i].RowIndex;
                        int columnIndex = dataGridView1.SelectedCells[i].ColumnIndex;
                        toggleDiggingForCell(rowIndex, columnIndex);
                    }
                    //clear selection, but the program still keeps track of the active cell
                    dataGridView1.ClearSelection();
                }
                //signal that the event has been dealt with, and should be ignored by
                //everyone else. This prevents the program from having a parent class
                //move the active cell down.
                e.Handled = true;
            }
            base.OnKeyDown(e);
        }

        //dig terrain
        private Action[,] createGridDig()
        {
            int nbRows = dataGridView1.Rows.Count;
            int nbColumns = dataGridView1.Rows[0].Cells.Count;
            Action[,] grid = new Action[nbRows, nbColumns];

            for (int i = 0; i < dataGridView1.Rows.Count; i++)
            {
                for (int j = 0; j < dataGridView1.Rows[i].Cells.Count; j++)
                {
                    if (dataGridView1.Rows[i].Cells[j].Style.BackColor == cellDigColor)
                    {
                        grid[i, j] = Action.Dig;
                    }
                    else
                    {
                        grid[i, j] = Action.None;
                    }
                }
            }
            return grid;
        }
        private void buttonRun_Click(object sender, EventArgs e)
        {
            //loadXML();
            /*buttonRun.Enabled = false;
            
            try
            {
                int startRowIndex, startColumnIndex;
                findStartingPosition(out startRowIndex, out startColumnIndex);

                Action[,] gridDig = createGridDig();
                DFcommands.Instance.digTerrain(startRowIndex, startColumnIndex, gridDig);
            }
            catch (Exception err)
            {
                string message = err.Message;
                string caption = "Error";
                MessageBox.Show(message, caption, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            
            buttonRun.Enabled = true;*/
        }
    }
}
